import matplotlib.pyplot as plt
import numpy as np

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号

# 模拟数据（基于论文描述的特性）
popularity_quantiles = ['0-10%', '10-20%', '20-30%', '30-40%', '40-50%', 
                        '50-60%', '60-70%', '70-80%', '80-90%', '90-100%']

# LightGCN（传统方法）：头部物品表现好，尾部物品表现差
lightgcn_recall = [0.42, 0.38, 0.35, 0.32, 0.29, 0.25, 0.21, 0.17, 0.13, 0.09]

# MACR（反事实方法）：尾部物品有一定提升
macr_recall = [0.38, 0.36, 0.34, 0.32, 0.30, 0.28, 0.26, 0.24, 0.22, 0.20]

# 本文方法（Ours）：在尾部物品上有显著提升
ours_recall = [0.40, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.32, 0.31]

# 创建专业图表
plt.figure(figsize=(8,4), dpi=300)

# 绘制折线图
plt.plot(popularity_quantiles, lightgcn_recall, 'b-o', linewidth=2.5, markersize=8, label='LightGCN')
plt.plot(popularity_quantiles, macr_recall, 'g--s', linewidth=2.5, markersize=8, label='MACR')
plt.plot(popularity_quantiles, ours_recall, 'r-^', linewidth=2.5, markersize=8, label='Ours')

# 添加数据标签（只显示关键点）
for i in range(len(popularity_quantiles)):
    # 头部物品（0-10%）
    if i == 0:
        plt.text(i, lightgcn_recall[i]+0.01, f'{lightgcn_recall[i]:.2f}', 
                 ha='center', va='bottom', fontsize=9, color='blue')
        plt.text(i, macr_recall[i]-0.01, f'{macr_recall[i]:.2f}', 
                 ha='center', va='top', fontsize=9, color='green')
        plt.text(i, ours_recall[i]+0.01, f'{ours_recall[i]:.2f}', 
                 ha='center', va='bottom', fontsize=9, color='red')
    
    # 尾部物品（90-100%）
    if i == 9:
        plt.text(i, lightgcn_recall[i]-0.01, f'{lightgcn_recall[i]:.2f}', 
                 ha='center', va='top', fontsize=9, color='blue')
        plt.text(i, macr_recall[i]-0.01, f'{macr_recall[i]:.2f}', 
                 ha='center', va='top', fontsize=9, color='green')
        plt.text(i, ours_recall[i]+0.01, f'{ours_recall[i]:.2f}', 
                 ha='center', va='bottom', fontsize=9, color='red')

# 设置标题和标签
# plt.title('不同流行度分位物品的Recall@10对比', fontsize=14, fontweight='bold', pad=15)
plt.xlabel('物品流行度分位（0-10%为头部，90-100%为尾部）', fontsize=12, fontweight='bold')
plt.ylabel('Recall@10', fontsize=12, fontweight='bold')

# 设置Y轴范围
plt.ylim(0.05, 0.45)

# 添加网格线
plt.grid(True, linestyle='--', alpha=0.3)

# 添加图例
plt.legend(loc='lower left', fontsize=12)

# 添加关键区域标注
plt.axvspan(0, 4, alpha=0.1, color='green', label='Head Items Region')
plt.axvspan(5, 9, alpha=0.1, color='red', label='Tail Items Region')
plt.text(2, 0.43, 'Head Items Region', fontsize=10, ha='center', color='green')
plt.text(7, 0.43, 'Tail Items Region', fontsize=10, ha='center', color='red')

# 添加性能提升标注
# plt.annotate('本文方法显著提升尾部物品召回率', 
#              xy=(9, 0.31), xytext=(6, 0.35),
#              arrowprops=dict(arrowstyle='->', color='black', lw=1.5),
#              fontsize=10, bbox=dict(facecolor='yellow', alpha=0.2))

# 添加尾部物品提升幅度计算
# tail_improvement_lightgcn = round((ours_recall[9] - lightgcn_recall[9](@ref) / lightgcn_recall[9] * 100, 1)
# tail_improvement_macr = round((ours_recall[9] - macr_recall[9](@ref) / macr_recall[9] * 100, 1)
# plt.text(9.2, 0.25, f'较LightGCN提升{tail_improvement_lightgcn}%', fontsize=9, color='blue')
# plt.text(9.2, 0.23, f'较MACR提升{tail_improvement_macr}%', fontsize=9, color='green')

# 优化布局
plt.tight_layout()

# 保存高质量图片
plt.savefig('recall_by_popularity.png', bbox_inches='tight', dpi=300)
plt.show()
